'use strict'

let Fiber = require('fibers');

let um = require('..');
let Types = require('..').Types;

um.enablePersist();
let session = um.createSession({
    backend: 'mongodb',
    uri: 'mongodb://localhost/userman',
    options: {
        //user: 'user',
        //pass: '123456'
    }
});

let Tag = um.model.createModel('Tag', {
    name: Types.Text()
});
let TagDao = session.getDao(Tag);

let Image = um.model.createModel('Image', {
    path: Types.Text(),
    type: Types.Text(),
    width: Types.Integer(),
    height: Types.Integer(),
    tags: Types.UObjectArray({
        type: 'Tag'
    })
});
let ImageDao = session.getDao(Image);

let User = um.model.createModel('User', {
    name: Types.Text(),
    age: Types.Integer(),
    height: Types.Double(),
    weight: Types.Double(),
    photo: Types.UObject({
        type: 'Image'
    })
});
let UserDao = session.getDao(User);

let File = um.model.createModel('File', {
    name: Types.Text(),
    createTime: Types.DateTime(),
    hidden: Types.Bool()
});
let FileDao = session.getDao(File);

let School = um.model.createModel('School', {
    name: Types.Text(),
    type: Types.Integer(),
    campuses: Types.UObjectArray({
        type: 'Campus'
    })
});
let SchoolDao = session.getDao(School);

let Campus = um.model.createModel('Campus', {
    name: Types.Text(),
    address: Types.Text(),
    school: Types.UObject({
        type: 'School'
    })
});
let CampusDao = session.getDao(Campus);

Fiber(function() {
    main();

    process.exit();
}).run();

function main() {
    let schoolId = recursiveCreate();
    recursiveFind(schoolId);
    recursiveFindInclude(schoolId);
}

function recursiveCreate() {
    SchoolDao.remove({});
    CampusDao.remove({});

    let school = new School({
        name: '合肥工业大学',
        type: 0
    });
    SchoolDao.create(school);

    let campus1 = new Campus({
        name: '屯溪路校区',
        address: '屯溪路',
        school: school
    });
    let campus2 = new Campus({
        name: '翡翠湖校区',
        address: '大学城',
        school: school
    });
    CampusDao.create(campus1);
    CampusDao.create(campus2);

    school.campuses = [
        campus1, campus2
    ];

    SchoolDao.update(school);

    return school.id;
}

function recursiveFindInclude(schoolId) {
    let school = SchoolDao.findOne({
        id: schoolId
    });

    let plainObject = school.toObject({
        includes: [
            'name',
            'type', 
            {
                campuses: [ 
                    'name'
                ] 
            }
        ]
    });

    console.log(JSON.stringify(plainObject));
}

function recursiveFind(schoolId) {
    let school = new School({
        id: schoolId
    });
    SchoolDao.refresh(school);

    console.log(JSON.stringify(
                school.toObject({
                    recursive: true
                })
    ));
}

function testDateBool() {
    let file = new File({
        id: '5657b5914aeb132016e1bdb9'
    });

    FileDao.refresh(file);
    console.log(file.toObject());
}

function createUser() {
    let user = new User();
    user.name = 'kkk';
    user.age = 28;
    user.height = 148;
    user.weight = 51.5;

    UserDao.create(user);
    console.log(user.toObject());
}

function createUser2() {
    let user = new User({
        name: 'ttt',
        age: 20,
        height: 155,
        weight: 50.5,
        photo: new Image({
            path: 'map.png',
            type: 'png',
            width: 500,
            height: 400,
            tags: [
                new Tag({
                    name: 'Color'
                }),
                new Tag({
                    name: 'High'
                })
            ]
        })
    });

    user.photo.tags.forEach(tag => {
        TagDao.create(tag);
    });

    ImageDao.create(user.photo);
    UserDao.create(user);

    console.log(user.toString());
    console.log(user.photo.toString());
    user.photo.tags.forEach(tag => {
        console.log(tag.toString());
    });
}

function autoLoad(userId) {
    let user = new User({
        id: userId
    });
    UserDao.refresh(user);
    console.log(JSON.stringify(user.toObject()));

    // The photo and tag will be auto loaded when you access the properties of these models.
    //console.log(user.name);
    //console.log(user.age);
    //console.log(user.height);
    //console.log(user.weight);
    //console.log(user.photo.toObject());
    //console.log(Tag.toObjectArray(user.photo.tags));
}

function findAllUsers() {
    let users = UserDao.find({});

    console.log(users.length);
    users.forEach(user => {
        console.log(user.toString());
    });
}

function findUsers() {
    let users = UserDao.find({
        name: 'World'
    });

    console.log(users.length);
    users.forEach(user => {
        console.log(user.toString());
    });
}

function findOneUser() {
    let user = UserDao.findOne({
        name: 'kkk'
    });

    if ( user != null ) {
        console.log(user.toString());
    }
    else {
        console.log(null);
    }
}

function getUser(userId) {
    let user = new User({
        id: userId
    });
    UserDao.refresh(user);

    console.log(user.toObject());
}

function updateUsers() {
    UserDao.update({
        name: 'Hello'
    }, {
        name: 'World'
    }, {
        multi: true
    });
}

function updateOneUser() {
    let user = UserDao.updateOne({
        name: 'World'
    }, {
        $set: {
            name: 'Hello'
        }
    }, {
        new: true
    });

    console.log(user.toString());
}

function updateSelf(userId) {
    let user = new User({
        id: userId
    });
    UserDao.refresh(user);
    console.log(user.toString());

    user.age = 25;

    UserDao.update(user);
    console.log(user.toString());
}

function removeUsers() {
    UserDao.remove({
        name: 'Hello'
    });
}

function removeOneUser(userId) {
    let user = new User();
    user.id = userId;
    UserDao.remove(user);
}

